import json
from functools import lru_cache, wraps
import time
from typing import List
from pydantic import BaseModel
from config import settings, ProductConfig
from sales_prediction import predict_daily_sales
from db_operations import save_yesterday_data_from_api, get_recent_7days_statistics
import aiohttp


def timed_lru_cache(seconds: int, maxsize: int = 128):
    def wrapper_cache(func):
        func = lru_cache(maxsize=maxsize)(func)
        func.lifetime = seconds
        func.expiration = time.time() + func.lifetime

        @wraps(func)
        def wrapped_func(*args, **kwargs):
            if time.time() >= func.expiration:
                func.cache_clear()
                func.expiration = time.time() + func.lifetime
            return func(*args, **kwargs)

        return wrapped_func

    return wrapper_cache


class ProductData(BaseModel):
    product_name: str
    reg_count: int
    uuid_count: int
    order_sum: float
    arpu: float
    last_arpu: float
    registration_rate: float
    predicted_sales: float
    percentage_change: float
    order_count: int
    # 新增近7日统计字段
    recent_7days_payment_rate: float = 0.0  # 近7日付费率
    recent_7days_arpu: float = 0.0  # 近7日ARPU
    recent_7days_avg_revenue: float = 0.0  # 近7日日均流水
    recent_7days_avg_order_value: float = 0.0  # 近7日客单价
    recent_7days_actual_days: int = 0  # 实际统计天数
    recent_7days_total_orders: int = 0  # 近7日总订单数
    recent_7days_total_users: int = 0  # 近7日总用户数
    recent_7days_total_revenue: int = 0  # 近7日总收入
    recent_7days_avg_new_users: int = 0  # 近7日日均新增用户


PRODUCT_NAME_MAPPING = {
    "aibangzhu": "爱帮主",
    "aiqinghua": "AI情话",
    "zhuiai": "追爱神器",
}


@timed_lru_cache(seconds=settings.CACHE_DURATION)
async def fetch_api_data(session, product_name: str, api_url: str):
    async with session.get(api_url) as response:
        if response.status != 200:
            return {"error": f"API请求失败，状态码为 {response.status}"}
        try:
            return await response.json()
        except aiohttp.ContentTypeError:
            text_content = await response.text()
            try:
                return json.loads(text_content)
            except json.JSONDecodeError:
                return {"error": "JSON解码失败", "content": text_content[:500]}


@lru_cache(maxsize=None)
def cache_key(url: str) -> str:
    return f"{url}_{int(time.time() / settings.CACHE_DURATION)}"


async def process_api_data(
    session: aiohttp.ClientSession, product_name: str, config: ProductConfig
):
    try:
        # 只保留 User-Agent
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
        }

        # print(f"Requesting {product_name} API: {config.api_url}")

        async with session.get(config.api_url, headers=headers) as response:
            # print(f"Response status for {product_name}: {response.status}")

            # 获取响应内容
            content = await response.text()

            if response.status != 200:
                print(f"API error for {product_name}: Status {response.status}")
                return []

            try:
                # 直接尝试解析返回的文本内容为JSON
                data = json.loads(content)
            except json.JSONDecodeError:
                print(f"Failed to parse response as JSON for {product_name}")
                print(f"Response content: {content[:200]}...")  # 打印部分内容用于调试
                return []

        if isinstance(data, dict) and len(data) > 0:
            # 检查是否是多产品数据（恋爱集合的情况）
            if any(key in data for key in ["aibangzhu", "aiqinghua", "zhuiai"]):
                # 处理多产品数据
                results = []
                for key, value in data.items():
                    # 保存昨日数据
                    save_yesterday_data_from_api(value, key)

                    # 使用 predict_daily_sales 计算预测值
                    predicted_sales = predict_daily_sales(
                        float(value.get("order_sum", 0)), key
                    )
                    product_data = process_single_product_data(key, value)
                    product_data["predicted_sales"] = predicted_sales
                    results.append(product_data)
                return results
            else:
                # 处理单产品数据 - 保存昨日数据
                save_yesterday_data_from_api(data, product_name)

                predicted_sales = predict_daily_sales(
                    float(data.get("order_sum", 0)), product_name
                )
                product_data = process_single_product_data(product_name, data)
                product_data["predicted_sales"] = predicted_sales
                return [product_data]
    except Exception as e:
        print(f"Error processing data for {product_name}: {e}")
        return []


def process_single_product_data(product_name: str, data: dict):
    try:
        # 打印原始数据，用于调试
        # print(f"Processing data for {product_name}: {data}")

        # 获取基础数据
        order_sum = float(data.get("order_sum", 0))
        reg_count = float(data.get("reg_count", 1))
        last_order_sum = float(data.get("last_order_sum", 0))

        # 计算ARPU
        arpu = (
            float(data.get("arpu", 0))
            if "arpu" in data
            else (order_sum / reg_count if reg_count > 0 else 0)
        )

        # 计算预估值的变化百分比
        predicted_sales = predict_daily_sales(order_sum, product_name)
        predicted_change = 0
        if last_order_sum > 0:
            predicted_change = (
                (predicted_sales - last_order_sum) / last_order_sum
            ) * 100

        # 确保预估值是整数
        predicted_sales = int(predicted_sales)

        # 获取近7日统计数据
        recent_stats = get_recent_7days_statistics(product_name)

        return {
            "product_name": PRODUCT_NAME_MAPPING.get(product_name, product_name),
            "order_sum": int(order_sum),  # 转为整数
            "arpu": round(arpu, 2),  # 保留两位小数
            "predicted_sales": predicted_sales,  # 已经确保是整数
            "predicted_change": round(predicted_change, 2),  # 保留两位小数
            "reg_count": int(data.get("reg_count", 0)),
            "order_count": int(data.get("order_count", 0)),
            "last_arpu": float(data.get("last_arpu", 0)),
            "last_order_sum": int(last_order_sum),  # 确保这个字段被正确返回
            # 新增近7日统计字段
            "recent_7days_payment_rate": recent_stats[
                "recent_7days_payment_rate"
            ],  # 近7日付费率
            "recent_7days_arpu": recent_stats["recent_7days_arpu"],  # 近7日ARPU
            "recent_7days_avg_revenue": recent_stats[
                "recent_7days_avg_revenue"
            ],  # 近7日日均流水
            "recent_7days_avg_order_value": recent_stats[
                "recent_7days_avg_order_value"
            ],  # 近7日客单价
            "recent_7days_actual_days": recent_stats["actual_days"],  # 实际统计天数
            "recent_7days_total_orders": recent_stats[
                "recent_7days_total_orders"
            ],  # 近7日总订单数
            "recent_7days_total_users": recent_stats[
                "recent_7days_total_users"
            ],  # 近7日总用户数
            "recent_7days_total_revenue": recent_stats[
                "recent_7days_total_revenue"
            ],  # 近7日总收入
            "recent_7days_avg_new_users": recent_stats[
                "recent_7days_avg_new_users"
            ],  # 近7日日均新增用户
        }
    except Exception as e:
        print(f"Error processing single product data for {product_name}: {e}")
        return {
            "product_name": PRODUCT_NAME_MAPPING.get(product_name, product_name),
            "order_sum": 0,
            "arpu": 0,
            "predicted_sales": 0,
            "predicted_change": 0,
            "reg_count": 0,
            "order_count": 0,
            "last_arpu": 0,
            "last_order_sum": 0,
            # 错误情况下的默认值
            "recent_7days_payment_rate": 0.0,
            "recent_7days_arpu": 0.0,
            "recent_7days_avg_revenue": 0,
            "recent_7days_avg_order_value": 0.0,
            "recent_7days_actual_days": 0,
            "recent_7days_total_orders": 0,
            "recent_7days_total_users": 0,
            "recent_7days_total_revenue": 0,
            "recent_7days_avg_new_users": 0,
        }
